package edu.cmich.cps.cps240.partyprincesspalace.hw06;

import java.awt.Point;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;


/**
 * A Pin interface, has abstract methods to be implemented by
 * WirePin and ChipPin.
 * @author holda1ja
 * @author kingm1sa
 */
public interface Pin {
	/**
	 * Gets the parent, or owner, of the pin.
	 * @return the current parent assigned to this pin.
	 * null if the pin does not currently have a parent
	 * assigned
	 */
	public WorkspaceObj getParent();
	
	/**
	 * Sets the parent, or owner, of the pin.  Note that
	 * if you change the owner, you should also make sure
	 * that the old parent does not have a dangling handle
	 * to the chip. 
	 * @param p_parent The new parent to assign to this pin.
	 * Pass in null if you wish to unassign the pin's parent.
	 */
	public void setParent(WorkspaceObj p_parent);
	
	/**
	 * Get the pin's partner which it is connected to
	 * @return the other pin which this pin is connected to
	 */
	public Pin getPartner();
	
	/**
	 * Sets the pin's partner which this pin is connected to.
	 * If the pin is already connected to a partner, then it
	 * should detach from the partner - guaranteeing that there
	 * are no dangling handles to either pin.
	 * @param p_partner The other pin which this pin will connect to
	 */
	public void setPartner(Pin p_partner);
	
	/**
	 * Gets the name of this pin.  For a wire, all input and
	 * output pins should have the same name.  For a chip,
	 * each input and output should have a unique name.
	 * @return The name of this pin.
	 */
	public String getName();
	
	/**
	 * Changes the name of this pin.  For a wire, all inputs and
	 * outputs should have the same name as the wire.
	 * @param p_name The new name that will refer to this chip
	 */
	public void setName(String p_name);
	
	/**
	 * @return true if this pin is an input pin on the parent/owner
	 */
	public boolean isInput();
	
	/**
	 * @return true if this pin is an output pin on the parent/owner
	 */
	public boolean isOutput();
	
	/**
	 * @return the location where this pin is located on the circuit
	 */
	public Point getLocation();
	
	/**
	 * Sets the location where this pin is located on the circuit.  The location
	 * should be guaranteed to be located "on" the pin's parent.
	 * @param p_location The new point where this pin is to be located on the circuit.
	 */
	public void setLocation(Point p_location);
	
	/**
	 * Determines if the given point is within a 10x10 area of the
	 * pin's current location.
	 * @param point A location on the workspace
	 * @return True if the given point is close to the pin, else false 
	 */
	public boolean closeToPin(Point point);
	
	/**
	 * Is necessary for the Serializable implementation. Passes a serialized version of the object to the
	 * ObjectOutputStream passed in as a parameter.
	 * @param out, an ObjectOutputStream to which the serialized version of this object is passed.
	 */
	public void writeObject(ObjectOutputStream out) throws IOException;
	
	/**
	 * Is necessary for the Serializable implementation. Creates an object from the
	 * ObjectInputStream passed in as a parameter.
	 * @param in, an ObjectInputStream from which to create the object.
	 */
	public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
}
